#!/bin/bash

# documentation: README.md
# or https://notabug.org/ohnonot/xscripts/blob/master/README.md

########################## FUNCTIONS BEGIN ####################################

adjust_xapps ()
{
echo "echo \"$1\" | xrdb -merge" >> "$xappspicker_rc"
}

adjust_dmenu ()
{
: ${dmenurc=$HOME/.config/dmenu/dmenurc}
if [ -w "$dmenurc" ]; then
  rm "$dmenurc"
  [ -n "$dmenufont" ] && echo -n "-fn $dmenufont " > "$dmenurc"
  echo "-nb ${fgbg[1]} -nf ${fgbg[0]} -sb ${fgbg[3]} -sf ${fgbg[2]} " >> "$dmenurc"
fi
}

adjust_xsetroot ()
{
#~ echo ". $SCRIPT_DIR/posix_compliant_random_functions" >> "$xappspicker_rc"

if [ -d "$bitmapdir" ] ;then
  #~ echo "xsetroot -fg \"$1\" -bg \"$2\" -bitmap \"\$(randombitmap \"$bitmapdir\")\"" >> "$xappspicker_rc"
  echo "xsetroot -fg \"$1\" -bg \"$2\" -bitmap \"\$(shuf -n1 -e $bitmapdir/*.xbm)\"" >> "$xappspicker_rc"
elif [ -f "$themepath/xsetrootbitmap.xbm" ] ;then
  echo "xsetroot -fg \"$1\" -bg \"$2\" -bitmap \"$themepath/xsetrootbitmap.xbm\"" >> "$xappspicker_rc"
else
  echo "xsetroot -fg \"$1\" -bg \"$2\" -mod \$(( \$(random)%15 + 2)) \$(( \$(random)%15 + 2))" >> "$xappspicker_rc"
fi
}

grepcol ()
{
# uses a tiny python2 snippet
# fgbg array: fgbg[0] is foreground, fgbg[1] is background
fgbg=($(python2 -c 'import gtk
w = gtk.Window()
w.realize()
style=w.get_style()
print style.fg[gtk.STATE_NORMAL].to_string()
print style.bg[gtk.STATE_NORMAL].to_string()
print style.text[gtk.STATE_SELECTED].to_string()
print style.base[gtk.STATE_SELECTED].to_string()' 2>/dev/null))
# the third one is the background for selected text, aka Highlight

hex12to6
}

hex12to6 ()
{
  for (( i=0 ; i<${#fgbg[@]} ; i++ ))
  do
    # simply discard the last 2 digits of each red, green and blue
    fgbg[i]="#${fgbg[i]:1:2}${fgbg[i]:5:2}${fgbg[i]:9:2}"
  done
}

invert ()
{
  # inverts colors
  r=${1:1:2}
  g=${1:3:2}
  b=${1:5:2}
  printf "#%02x%02x%02x\n" $((16#FF - 16#$r)) $((16#FF - 16#$g)) $((16#FF - 16#$b))
}

hextriplet2float ()
{
  # convert the hex representation of one of r,g,b to a float between 0 and 1
  bc<<<"obase=10; ibase=16; scale=3; $1/FF"
}
float255 ()
{
  # multiply a float between 0 and 1 by 255, doh.
  bc<<<"$1*255"
}
fixed_value ()
{
  # sets the value of color $1 (format: #nnnnnn) to $2 (a float between 0 and 1),
  # leaving hue and saturation intact, and returns the resulting color.
  r=${1:1:2}
  r="$(hextriplet2float ${r^^})"
  g=${1:3:2}
  g="$(hextriplet2float ${g^^})"
  b=${1:5:2}
  b="$(hextriplet2float ${b^^})"
  rgb="$r,$g,$b"
  hsv="$(python2 -c "import colorsys
print colorsys.rgb_to_hsv($rgb)")"

  huesat="${hsv%,*}"
  huesat="${huesat##*(}"
  hsv="$huesat,$2"
  rgb="$(python2 -c "import colorsys
print colorsys.hsv_to_rgb($hsv)")"

  rg="${rgb%,*}"
  r="${rg%%,*}"
  r="${r##*(}"
  g="${rg##*,}"
  b="${rgb##*,}"
  b="${b%%)*}"

  r="$(float255 $r)"
  r="${r%%.*}"
  g="$(float255 $g)"
  g="${g%%.*}"
  b="$(float255 $b)"
  b="${b%%.*}"
  printf "#%02x%02x%02x" $r $g $b
}


adjust_tint2 ()
{
# when sourcing $xappspicker_rc without running this script, tint2 is NOT killed!
if [ -r "$xappspicker_dir/tint2_pid" ]; then
  tint2pid="$(< "$xappspicker_dir/tint2_pid")"
  [[ "$(ps -q $tint2pid -o comm=)" == "tint2" ]] && kill $tint2pid
  unset tint2pid
  rm "$xappspicker_dir/tint2_pid"
fi
tint2dir="$HOME/.themes/$GTK2_CURRENT_THEME/tint2"
if [ -r "$tint2dir/tint2rc" ];then
  echo "cd \"$tint2dir\"" >> "$xappspicker_rc"
  echo "tint2 -c \"./tint2rc\" &" >> "$xappspicker_rc"
  echo "echo \$! > \"$xappspicker_dir/tint2_pid\"" >> "$xappspicker_rc"
elif [[ "$tint2_is_essential" == "1" ]]; then
  echo "tint2 &" >> "$xappspicker_rc"
  echo "echo \$! > \"$xappspicker_dir/tint2_pid\"" >> "$xappspicker_rc"
fi
}

adjust_conky ()
{
kill $(pgrep -f 'conky -a xappspicker_identifier*')
# conky changes its pid when it has the "background yes" configuration option,
# and so saving $! to a pidfile saves the wrong pid.
# instead, we uniquely identify this instance of conky by launching it with a bogus
# command line option.
conkydir="$HOME/.themes/$GTK2_CURRENT_THEME/conky"
if [ -r "$conkydir/conkyrc" ];then
  echo "cd \"$conkydir\"" >> "$xappspicker_rc"
  echo "conky -a xappspicker_identifier -c \"./conkyrc\" &" >> "$xappspicker_rc"
elif [[ "$conky_is_essential" == "1" ]]; then
  echo "conky -a xappspicker_identifier &" >> "$xappspicker_rc"
fi
}

change_openbox_theme ()
{
if [ -r "$HOME/.themes/$GTK2_CURRENT_THEME/openbox-3/themerc" ] || [ -r "/usr/share/themes/$GTK2_CURRENT_THEME/openbox-3/themerc" ] ; then
  : ${obrc=$HOME/.config/openbox/rc.xml}
  theme="$(xmllint --html --nonet --xpath '//openbox_config/theme/name' "$obrc" 2>/dev/null)"
  theme="${theme%%</*>}"
  if [[ "x$theme" != "x" ]] ; then
    mv -f "$obrc.xappspicker.bak" "$obrc.xappspicker.bak2"
    cp "$obrc" "$obrc.xappspicker.bak"
    sed -i "s/$theme/<name>$GTK2_CURRENT_THEME/" "$obrc"
    openbox --reconfigure
  fi
fi
}
######################## FUNCTIONS END ########################################

######################## MAIN BEGIN ###########################################

# the directory where the script itself (and files it depends upon) resides.
# ( symlinking the executable to e.g. $HOME/bin does not break this )
SCRIPT_DIR="$(readlink "$0")"
if [ -z "$SCRIPT_DIR" ]; then
  SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
else
  SCRIPT_DIR="${SCRIPT_DIR%/*}"
fi

### GTK2_RC_FILES is probably already part of the env (at least on my systems)
### https://stackoverflow.com/a/11686912
: ${GTK2_RC_FILES=$HOME/.gtkrc-2.0}
# the latter we have to redo time and again, otherwise the script won't work
# when run manually after a theme change.
GTK2_CURRENT_THEME="$($(which grep) gtk-theme-name $GTK2_RC_FILES|cut -d\" -f2)"
if [ -f  "$HOME/.themes/$GTK2_CURRENT_THEME/gtk-2.0/gtkrc" ]
then 
       themepath="$HOME/.themes/$GTK2_CURRENT_THEME"
else
       themepath="/usr/share/themes/$GTK2_CURRENT_THEME"
fi

# heavy lifting starts here
grepcol

base_fg="${fgbg[0]}"
base_bg="${fgbg[1]}"
sel_txt_fg="${fgbg[2]}"
sel_txt_bg="${fgbg[3]}"

if [ -r "$HOME/.config/xappspicker/config" ]; then
  . "$HOME/.config/xappspicker/config"
elif [ -r "$SCRIPT_DIR/config" ]; then
  . "$SCRIPT_DIR/config"
else
  echo "Fatal: Could not find config file in
$HOME/.config/xappspicker/config
$SCRIPT_DIR/config

Exiting.
"
  exit 1
fi

rm -f "$xappspicker_rc"
mkdir -p "$xappspicker_dir"

# prepare the values for xsetroot. please see man xsetroot.
# 1.: do you want to choose a random bitmap from the following dir?
#     if not, set this to "", and xsetroot will choose:
#      a) the file xsetrootbitmap.xbm from $themedir, or, failing that
#      b) a random -mod.
bitmapdir="$SCRIPT_DIR/$bitmapdir"
# 2.: which color to choose as a base for the background? I choose the background for
#     selected text, usually the most colorful accent in the theme. It's the 4th and
#     last color in the array generated by grepcol() = ${fgbg[3]}
# 3.: manipulate that color. 
#     a) i prefer to darken the background to 20%, and the foreground to 10%
#~ xsetrootbg="$(fixed_value "${fgbg[3]}" "0.2")"
#~ xsetrootfg="$(fixed_value "${fgbg[3]}" "0.1")"
#     b) another possibility: color-invert (=negative) the colors
#~ xsetrootbg="$(invert "${fgbg[0]}")" # that is the foreground
#~ xsetrootfg="$(invert "${fgbg[1]}")" # that is the background
# functions can be combined, too.
[[ "$xapps_enabled" == "1" ]] && adjust_xapps "$xres"

# which xapps will be affected?
# un/comment or add desired values in config file.
if [[ "$xsetroot_enabled" == "1" ]]; then
  adjust_xsetroot "$xsetrootfg" "$xsetrootbg"
else
  [[ "$feh_instead_of_xsetroot" == "1" ]] && echo '. ~/.fehbg &' >> "$xappspicker_rc"
fi

# adjusting dmenu is simpler, we take all 4 colors from the array:
# base fore/background, selected text fore/background.
# since dmenu is not an Xapp, this is optional.
# set to empty string to disable.
#~ dmenurc="$HOME/.config/dmenu/dmenurc"
# font definitions in dmenu 4.6 are unclear to me. they also differ from
# suckless-tools 4.5 - one cannot pass xfont-strings.
# the one below should work on all systems, or at least fail silently.
# set to empty string to use default font.
#~ dmenufont="terminus"
[[ "$dmenu_enabled" == "1" ]] && adjust_dmenu

# looks for a file tint2rc in a tint2 subfolder inside your theme folder
# i.e. $themepath/tint2/tint2rc
[[ "$tint2_enabled" == "1" ]] && adjust_tint2
# looks for a file conkyrc in a conky subfolder inside your theme folder,
# i.e. $themepath/conky/conkyrc
[[ "$conky_enabled" == "1" ]] && adjust_conky

[[ "$openbox_enabled" == "1" ]] && change_openbox_theme

# if this file exists, and it is executable, then execute it.
# this should usually be the last line added to "$xappspicker_rc"
if [[ "$exec_enabled" == "1" ]]; then
  [[ "x$exec_path" == "x" ]] && exec_path="$themepath/xappspicker.exec"
  [ -x "$exec_path" ] && echo "\"$exec_path\" &" >> "$xappspicker_rc"
fi

# please do not remove this
. "$xappspicker_rc"
